import { Body, Controller, Logger, Post, Headers, Param, NotFoundException } from '@nestjs/common';
import { ApiBearerAuth, ApiExcludeController, ApiOperation, ApiTags } from '@nestjs/swagger';
import { ApiResult } from '~/common/decorators/api-result.decorator';
import { AuthService } from './auth.service';
import { Public } from './decorators/public.decorator';
import { LoginDto } from './dto/auth.dto';
import { LoginToken } from './models/auth.model';
import { decrypt } from '~/utils';
import { BusinessException } from '~/common/exceptions/biz.exception';
import { ErrorEnum } from '~/constants/error-code.constant';
import { AuthUser } from './decorators/auth-user.decorator';
import { AllowAnon } from './decorators/allow-anon.decorator';
import { AuthToken } from '~/common/decorators/auth-token.decorator';

@ApiTags('Auth - 认证模块')
@ApiBearerAuth()
@Controller('cms/auth')
export class AuthController {
  private readonly logger = new Logger(AuthController.name);

  constructor(
    private authService: AuthService
  ) {}

  @Public()
  @Post('login')
  @ApiOperation({ summary: '登录' })
  @ApiResult({ type: LoginToken })
  async login(@Body() dto: LoginDto): Promise<string> {
    try {
      dto.password = decrypt(dto.password);
    } catch (error) {
      throw new BusinessException(ErrorEnum.DECRYPT_FAILED);
    }
    return await this.authService.login(dto);
  }

	@Public()
	@Post('login/raw')
	@ApiOperation({ summary: '登录 - 使用明文密码' })
	@ApiResult({ type: LoginToken })
	async loginRaw(@Body() dto: LoginDto): Promise<string> {
		return await this.authService.login(dto);
	}

	@AllowAnon()
	@Post('logout')
	@ApiOperation({ summary: '登出' })
	async logout(@AuthUser() user: IAuthUser, @AuthToken() token: string): Promise<void> {
		this.logger.debug(`logout user: ${user.uid}`);

		if (!user || !token) {
			throw new BusinessException(ErrorEnum.INVALID_LOGIN);
		}

		this.authService.clearLoginStatus(user, token);
	}

	@Public()
	@Post('dev/:id')
	@ApiOperation({ summary: '获取开发者token' })
	async getDevToken(@Param('id') id: number) {
		if (process.env.NODE_ENV !== 'development') {
			throw new NotFoundException('Not Found');
		}

		return await this.authService.getDevTempToken(id);
	}
}
